package cn.yi.boot.mq.rocketmq.yml;

import cn.yi.boot.mq.rocketmq.message.handler.MessageHandler;
import com.google.common.base.Splitter;
import com.google.common.collect.Maps;
import lombok.Setter;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 解析yaml文件，获取topic与Tag之间的处理器的关系
 */
public class  YmlTopic2MessageHandlerFactoryBean implements FactoryBean<Map<String, Map<String, MessageHandler>>>, InitializingBean {

    @Setter
    private Map<String, Object> ymlMap;

    @Setter
    private List<MessageHandler> messageHandlers;

    private Map<String, Map<String, MessageHandler>> topic2TagHandler;

    @Override
    public Map<String, Map<String, MessageHandler>> getObject() throws Exception {
        return topic2TagHandler;
    }

    @Override
    public Class<?> getObjectType() {
        return Map.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        initHandler(ymlMap);
    }

    private void initHandler(Map<String, Object> ymlMap) {
        topic2TagHandler = new HashMap<>(ymlMap.size());
        //将类名与MessageHandler组成Map
        Map<String, MessageHandler> messageHandlerMap = Maps.newHashMap();
        messageHandlers.forEach(messageHandler -> {
            messageHandlerMap.put(messageHandler.getClass().getAnnotation(Component.class).value(), messageHandler);
        });
        ymlMap.forEach((topics, tags) -> {
            if (topics.startsWith("[") && topics.endsWith("]")) {
                topics = topics.substring(1, topics.length() - 1);
            }
            String tagStr = tags.toString();
            if (tagStr.toString().startsWith("[") && tagStr.toString().endsWith("]")) {
                tagStr = tagStr.toString().substring(1, tagStr.length() - 1);
            }
            Map<String,MessageHandler> tagMessageHandlerMap = Maps.newHashMap();
            for (String tag : Splitter.on("|").splitToList(tagStr)) {
                MessageHandler tagMessageHandler = messageHandlerMap.get(tag);
                if (Objects.nonNull(tagMessageHandler)) {
                    tagMessageHandlerMap.put(tag, tagMessageHandler);
                } else {
                    throw new RuntimeException("Tag无法获取到对应的Handler");
                }
            }

            for (String topic : Splitter.on("|").splitToList(topics)) {
                topic2TagHandler.put(topic, tagMessageHandlerMap);
            }
        });
    }
}
